﻿/***********************************************************************
 * <copyright file="RoleController.cs" company="B/S JSC">
 * -->    Copyright (C) statement. All right reserved
 * </copyright>
 * 
 * Created:   Hoang Bich Son 
 * Email:    sonhb@newman.vn
 * Website:
 * Create Date: Friday, March 21, 2014
 * Usage: 
 * 
 * RevisionHistory: 
 * Date         Author               Description 
 * 
 * ************************************************************************/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using DXWebApplication.Areas.Administrators.Controllers;
using DxMvcApplication.Areas.Administrator.Models;
using DxMvcApplication.Repositories.Implementations.Security;
using DxMvcApplication.SecurityServiceReference;
using Newtonsoft.Json;

namespace DxMvcApplication.Areas.Administrator.Controllers.Security
{
    public class RoleController : AdminBaseController, IAdminBaseController<RoleModel>
    {
        private readonly RoleRepository _roleRepository;
        private readonly SiteRepository _siteRepository;        
        private readonly PermissionRepository _permissionRepository;
        private readonly PermissionInSiteRepository _permissionInSiteRepository;

        /// <summary>
        /// Initializes a new instance of the <see cref="RoleController"/> class.
        /// </summary>
        public RoleController()
        {
            _roleRepository = new RoleRepository();
            _siteRepository = new SiteRepository();
            _permissionRepository = new PermissionRepository();
            _permissionInSiteRepository = new PermissionInSiteRepository();
        }


        /// <summary>
        /// Inserts this instance.
        /// </summary>
        /// <returns></returns>        
        [HttpGet]
        public PartialViewResult Insert()
        {
            var result = new RoleModel();
            return PartialView("RoleDetail", result);
        }

        /// <summary>
        /// Inserts the specified model.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>        
        [HttpPost]
        public JsonResult Insert(RoleModel model)
        {
            var msg = string.Empty;
            if (ModelState.IsValid)
            {
                msg = _roleRepository.Insert(model.FromModel());
            }
            return Json(new { message = msg });
        }

        /// <summary>
        /// Updates this instance.
        /// </summary>
        /// <param name="idJson">The identifier json.</param>
        /// <returns></returns>       
        [HttpGet]
        public PartialViewResult Update(string idJson)
        {
            var idList = JsonConvert.DeserializeObject<IList<int>>(idJson);
            var model = new RoleModel();
            if (idList.Count == 1)
            {
                int id;
                int.TryParse(idList[0].ToString(CultureInfo.InvariantCulture), out id);
                if (id > 0)
                {
                    model = _roleRepository.Get(id).ToModel();
                }
            }
            return PartialView("RoleDetail", model);
        }

        /// <summary>
        /// Updates the specified model.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>        
        [HttpPost]
        public JsonResult Update(RoleModel model)
        {
            var msg = string.Empty;
            if (ModelState.IsValid)
            {
                msg = _roleRepository.Update(model.FromModel());
            }
            return Json(new { message = msg });
        }

        /// <summary>
        /// Deletes the specified ids.
        /// </summary>
        /// <param name="idJson">The identifier json.</param>
        /// <returns></returns>        
        public JsonResult Delete(string idJson)
        {
            string msg;
            try
            {
                var idList = JsonConvert.DeserializeObject<IList<int>>(idJson);
                msg = _roleRepository.Delete(idList);
            }
            catch (Exception)
            {
                return Json(new { message = NmResources.MessageResource.Exception }, JsonRequestBehavior.AllowGet);
            }
            return Json(new { message = msg }, JsonRequestBehavior.AllowGet);
        }


        /// <summary>
        /// Gets the paged.
        /// </summary>
        /// <param name="currentPage">The current page.</param>
        /// <returns></returns>
        public PartialViewResult GetPaged(int currentPage = 1)
        {
            var totalPage = 0;
            var result = _roleRepository.GetPaged(ref totalPage, currentPage);
            ViewBag.TotalPage = totalPage;
            ViewBag.CurrentPage = currentPage;
            return PartialView("Role", result.ToModel());
        }

        /// <summary>
        /// Assigns to role.
        /// </summary>
        /// <param name="idJson">The identifier json.</param>
        /// <returns></returns>
        [HttpGet]
        public PartialViewResult AssignToRole(string idJson)
        {
            try
            {
                var idList = JsonConvert.DeserializeObject<List<int>>(idJson);
                if (idList.Count == 1)
                {
                    var roleId = idList[0];
                    if (roleId > 0)
                    {
                        ViewBag.RoleId = roleId;
                        ViewBag.AssignToRole = AssignToRoleHtml(roleId);
                    }
                }
                return PartialView();
            }
            catch (Exception e)
            {                
                throw;
            }
        }

        /// <summary>
        /// Assigns to role.
        /// </summary>
        /// <param name="roleId">The role identifier.</param>
        /// <param name="tableJson">The table json.</param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult AssignToRole(int roleId,string tableJson)
        {
            var msg = string.Empty;
            try
            {
                var jsonData = JsonConvert.DeserializeObject<List<RoleInSiteDto>>(tableJson);
                if (roleId > 0 && jsonData.Count > 0)
                {
                    msg = _roleRepository.AssignToRole(roleId, jsonData);
                }
            }
            catch (Exception)
            {
                return Json(new { message = NmResources.MessageResource.Exception });
            }
            return Json(new { message = msg });            
        }
        #region Assign
        public MvcHtmlString AssignToRoleHtml(int id)
        {
            var siteList = _siteRepository.GetList();
            var permissionList = _permissionRepository.GetList();
            var parents = siteList.Where(x => x.ParentId == 0);
            var lev = 1;
            //defined tag
            var tag = new TagBuilder("li");
            var spanTags = new TagBuilder("span");
            spanTags.AddCssClass("title col200");
            spanTags.SetInnerText("Danh mục / Quyền");
            tag.InnerHtml += spanTags;
            foreach (var per in permissionList)
            {
                var tdTags = new TagBuilder("span");
                tdTags.AddCssClass("title col100");
                tdTags.SetInnerText(per.Title);
                tag.InnerHtml += tdTags;
            }
            
            foreach (var site in parents)
            {
                var roleInSites = _roleRepository.GetRoleInSiteBySite(site.Id);
                var permissionInSite = _permissionInSiteRepository.GetPermissionInSiteBySiteId(site.Id);
                var trTags = new TagBuilder("li");
                trTags.MergeAttribute("id", site.Id.ToString(CultureInfo.InvariantCulture));
                trTags.MergeAttribute("class", "tr" + lev);
                var tdTags = new TagBuilder("span");
                tdTags.AddCssClass("title col200");
                tdTags.SetInnerText(site.Title);
                //tdTags.AddCssClass("lev" + lev);
                trTags.InnerHtml += tdTags;
                foreach (var per in permissionList)
                {
                    var tempTags = new TagBuilder("span");
                    tempTags.AddCssClass("title col100");
                    var inputTags = new TagBuilder("input");
                    var hasPermission = permissionInSite.SingleOrDefault(x => x.PermissionId == per.Id && x.SiteId == site.Id);
                    Dictionary<string, string> attrs;
                    if (hasPermission != null)
                    {
                        var hasRoleInSite = roleInSites.SingleOrDefault(x => x.PermissionId == per.Id && x.SiteId == site.Id && x.RoleId == id);
                        var perId = per.Id.ToString(CultureInfo.InvariantCulture);
                        if (hasRoleInSite != null)
                        {
                            attrs = new Dictionary<string, string>() { { "type", "checkbox" }, { "value", perId }, { "checked", "" } };
                        }
                        else
                        {
                            attrs = new Dictionary<string, string>() { { "type", "checkbox" }, { "value", perId } };
                        }
                    }
                    else
                    {
                        attrs = new Dictionary<string, string>() { { "type", "checkbox" }, { "value", "0" }, { "disabled", "" } };
                    }
                    inputTags.MergeAttributes(attrs);
                    tempTags.InnerHtml += inputTags;
                    trTags.InnerHtml += tempTags;
                }
                tag.InnerHtml += trTags;
                var childrens = siteList.Where(x => x.ParentId == site.Id).ToList();
                if (childrens.Count > 0)
                {
                    lev++;
                    GetInnerTag(id, lev, site.Id, siteList, permissionList, tag);
                    lev--;
                }
            }
            return MvcHtmlString.Create(tag.ToString());
        }
        protected virtual TagBuilder GetInnerTag(int roleId, int lev, int parentId, List<SiteDto> siteList, List<PermissionDto> permissionList, TagBuilder tag)
        {
            var parents = siteList.Where(x => x.ParentId == parentId).ToList();
            var trTags = new TagBuilder("tbody");
            foreach (var site in parents)
            {
                var roleInSites = _roleRepository.GetRoleInSiteBySite(site.Id);
                var permissionInSite = _permissionInSiteRepository.GetPermissionInSiteBySiteId(site.Id);
                trTags = new TagBuilder("li");
                trTags.MergeAttribute("id", site.Id.ToString(CultureInfo.InvariantCulture));
                trTags.MergeAttribute("class", "tr" + lev);
                var tdTags = new TagBuilder("span");
                tdTags.AddCssClass("title col200");
                tdTags.SetInnerText(site.Title);
                //tdTags.AddCssClass("lev" + lev);
                trTags.InnerHtml += tdTags;
                foreach (var per in permissionList)
                {
                    var tempTags = new TagBuilder("span");
                    tempTags.AddCssClass("title col100");
                    var inputTags = new TagBuilder("input");
                    var hasPermission = permissionInSite.SingleOrDefault(x => x.PermissionId == per.Id && x.SiteId == site.Id);
                    Dictionary<string, string> attrs;
                    if (hasPermission != null)
                    {
                        var hasRoleInSite = roleInSites.SingleOrDefault(x => x.PermissionId == per.Id && x.SiteId == site.Id && x.RoleId == roleId);
                        var perId = per.Id.ToString(CultureInfo.InvariantCulture);
                        if (hasRoleInSite != null)
                        {
                            attrs = new Dictionary<string, string>() { { "type", "checkbox" }, { "value", perId }, { "checked", "" } };
                        }
                        else
                        {
                            attrs = new Dictionary<string, string>() { { "type", "checkbox" }, { "value", perId } };
                        }
                    }
                    else
                    {
                        attrs = new Dictionary<string, string>() { { "type", "checkbox" }, { "value", "0" }, { "disabled", "" } };
                    }
                    inputTags.MergeAttributes(attrs);
                    tempTags.InnerHtml += inputTags;
                    trTags.InnerHtml += tempTags;
                }
                tag.InnerHtml += trTags;
                var childrens = siteList.Where(x => x.ParentId == site.Id).ToList();
                if (childrens.Count > 0)
                {
                    lev++;
                    GetInnerTag(roleId, lev, site.Id, siteList, permissionList, tag);
                    lev--;
                }
            }
            return trTags;
        }
        #endregion
    }
}
